package com.ruoyi.business.service.product.impl;


import com.alibaba.excel.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.dto.admin.product.ExamineOrderDTO;
import com.ruoyi.business.domain.dto.admin.product.OrderDTO;
import com.ruoyi.business.domain.dto.api.user.CreateOrderDTO;
import com.ruoyi.business.domain.enums.OrderSource;
import com.ruoyi.business.domain.enums.OrderStatus;
import com.ruoyi.business.domain.enums.OrderType;
import com.ruoyi.business.domain.jackyun.*;
import com.ruoyi.business.domain.koc.TbProductExchangeCoupon;
import com.ruoyi.business.domain.koc.TbUser;
import com.ruoyi.business.domain.koc.TbUserKocPointsLog;
import com.ruoyi.business.domain.koc.TbUserKocProductLog;
import com.ruoyi.business.domain.product.TbOrder;
import com.ruoyi.business.domain.product.TbOrderItem;
import com.ruoyi.business.domain.product.TbProduct;
import com.ruoyi.business.domain.product.TbProductSkus;
import com.ruoyi.business.domain.vo.order.OrderVo;
import com.ruoyi.business.domain.vo.product.OrderExamineVo;
import com.ruoyi.business.mapper.TbProductMapper;
import com.ruoyi.business.mapper.koc.*;
import com.ruoyi.business.mapper.product.TbOrderItemMapper;
import com.ruoyi.business.mapper.product.TbOrderMapper;
import com.ruoyi.business.mapper.product.TbProductSkusMapper;
import com.ruoyi.business.service.product.TbOrderService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.business.CouponStatusEnum;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单Service业务层处理
 */
@Service
@RequiredArgsConstructor
public class TbOrderServiceImpl extends ServiceImpl<TbOrderMapper, TbOrder> implements TbOrderService {

    private final TbProductSkusMapper tbProductSkusMapper;
    private final TbUserMapper tbUserMapper;
    private final TbOrderItemMapper tbOrderItemMapper;
    private final TbProductMapper tbProductMapper;
    private final TbUserAddressMapper tbUserAddressMapper;
    private final TbOrderMapper tbOrderMapper;
    private final TbUserKocPointsLogMapper tbUserKocPointsLogMapper;
    private final JackClent jackClent;
    private final TbProductExchangeCouponMapper tbProductExchangeCouponMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<TbOrder> pointsMallCreate(Long userId, CreateOrderDTO dto) {
        TbUser tbUser = tbUserMapper.selectById(userId);
        TbProductSkus sku = tbProductSkusMapper.selectById(dto.getSkuId());
        TbProduct product = tbProductMapper.selectById(sku.getProductId());
        Long totalPoints = sku.getPointsNeeded() * dto.getQuantity();// 总扣减积分
        BigDecimal totalCash = sku.getPrice().multiply(new BigDecimal(dto.getQuantity())); // 总支付金额
        R r = checkPointsExchangeEligibility(tbUser, sku, dto.getQuantity(),dto.getIsUserCoupon(),dto.getCouponIds());
        Integer orderType = sku.getExchangeType();// 1-纯积分，2-积分+金额 3koc产品兑换
        if (r.getCode() == R.fail().getCode()) {
            return R.fail(r.getMsg());
        }
        String orderNo = "ORD-PTS-" + DateUtils.format(new Date(), "yyyyMMddHHmmss") + RandomUtils.nextInt(1000, 9999); // 积分订单编号前缀
        TbOrder order = new TbOrder();
        order.setOrderNo(orderNo);
        order.setUserId(userId);
        order.setOrderSource(2); // 2-积分商城
        order.setOrderStatus(1); // 1-待支付（纯积分订单直接设为2-已支付）
        order.setAddressId(dto.getAddressId());
        order.setCreateTime(new Date());
        TbOrderItem orderItem = new TbOrderItem();
        orderItem.setOrderNo(orderNo);
        orderItem.setProductId(product.getId());
        orderItem.setProductTitle(product.getTitle());
        orderItem.setSkuId(dto.getSkuId());
        orderItem.setSkuCode(sku.getSkuCode());
        orderItem.setSpecsText(sku.getSpecsText());
        orderItem.setQuantity(Long.valueOf(dto.getQuantity()));
        orderItem.setBarcode(sku.getBarcode());
        orderItem.setCreateTime(new Date());
        orderItem.setPointsStockDeduct(Long.valueOf(dto.getQuantity()));
        if (dto.getIsUserCoupon()){
            //koc产品兑换
            orderType=3;
            order.setOrderType(orderType);
            order.setTotalPoints(Long.valueOf(0));
            order.setTotalCash(BigDecimal.valueOf(0));
            order.setPayType(4); // 4koc产品兑换
            baseMapper.insert(order);
            orderItem.setOrderId(order.getId());
            orderItem.setExchangeType(orderType);
            orderItem.setPointsNeeded(0L);
            orderItem.setCashNeeded(BigDecimal.valueOf(0));
            orderItem.setTotalPoints(0L);
            orderItem.setTotalCash(BigDecimal.valueOf(0));
            tbOrderItemMapper.insert(orderItem);
        }else {
            // 4. 创建订单（积分商城来源）
            order.setOrderType(orderType);
            order.setTotalPoints(totalPoints);
            order.setTotalCash(totalCash);
            order.setPayType(orderType == 1 ? 3 : 1); // 纯积分=3，积分+金额=微信支付（1）
            baseMapper.insert(order);

            // 5. 创建订单明细
            orderItem.setOrderId(order.getId());
            orderItem.setExchangeType(orderType);
            orderItem.setPointsNeeded(sku.getPointsNeeded());
            orderItem.setCashNeeded(sku.getPrice());
            orderItem.setTotalPoints(totalPoints);
            orderItem.setTotalCash(totalCash);
            tbOrderItemMapper.insert(orderItem);

            // 6. 冻结用户积分（避免并发下单重复扣减，支付完成后转扣减）
            tbUser.setFreePoints(tbUser.getFreePoints() - totalPoints.intValue());
            tbUser.setFrozenPoints(tbUser.getFrozenPoints() + totalPoints.intValue());
            tbUserMapper.updateById(tbUser);
        }
        // 7. 扣减SKU积分库存（冻结状态，支付完成后确认扣减）
        sku.setStock(sku.getStock() - dto.getQuantity());
        tbProductSkusMapper.updateById(sku);
        // 8. 分场景处理支付（纯积分直接完成，积分+金额需发起支付）
        if (orderType == 1) {
            // 纯积分订单：无需支付金额，直接标记已支付
            // 8.1 解冻积分并转为扣减
            tbUser.setFrozenPoints(tbUser.getFrozenPoints() - totalPoints.intValue());
            tbUser.setTotalPoints(tbUser.getTotalPoints() - totalPoints.intValue());
            tbUserMapper.updateById(tbUser);
            // 8.2 新增积分扣减流水
            addPointsFlow(tbUser, 2, orderNo, -totalPoints, "纯积分兑换商品：" + product.getTitle());
            // 8.3 更新订单状态为已支付
            order.setOrderStatus(7);
            order.setPayTime(new Date());
            tbOrderMapper.updateById(order);
        }
        if (orderType == 2) {
            //todo 后面做
        }
        //koc产品兑换
        if (orderType == 3){
            //修改使用koc产品兑换状态
            TbProductExchangeCoupon tbProductExchangeCoupon = new TbProductExchangeCoupon();
            tbProductExchangeCoupon.setStatus(CouponStatusEnum.USED.getCode());
            tbProductExchangeCoupon.setOrderId(order.getId());
            tbProductExchangeCoupon.setUseTime(new Date());
            tbProductExchangeCouponMapper.update(tbProductExchangeCoupon,new LambdaQueryWrapper<>(TbProductExchangeCoupon.class)
                .in(TbProductExchangeCoupon::getId,dto.getCouponIds()));

            order.setOrderStatus(7);
            order.setPayTime(new Date());
            tbOrderMapper.updateById(order);
        }
        return R.ok(order);
    }

    @Override
    public R<List<OrderExamineVo>> orderExamine(ExamineOrderDTO examineOrderDTO) {
        List<OrderExamineVo> list = new ArrayList<>();
        //纯积分，兑换需要审核，订单状态是7
        List<TbOrder> orders = tbOrderMapper.selectList(new LambdaQueryWrapper<>(TbOrder.class)
            .in(TbOrder::getId, examineOrderDTO.getIds())
            .eq(TbOrder::getOrderStatus, OrderStatus.PAYMENT_APPROVAL_PENDING.getCode())
            .eq(TbOrder::getOrderSource, OrderSource.POINTS_MALL.getCode()));
        for (TbOrder order:orders) {
            OrderExamineVo orderExamineVo = new OrderExamineVo();
            orderExamineVo.setExamineStatus(true);
            orderExamineVo.setOrderNo(order.getOrderNo());
            try {
                if (examineOrderDTO.getExamineStatus() == 0) {
                    order.setOrderStatus(OrderStatus.CANCELLED.getCode());
                    order.setUpdateTime(new Date());
                    order.setCancelTime(new Date());
                    tbOrderMapper.updateById(order);
                    //审核失败  归还积分，库存，记录积分流水，订单状态已取消
                    doOrderCancel(order);
                }
                if (examineOrderDTO.getExamineStatus() == 1) {
                    //查询erp库存是否足
                    Boolean  enough = jackClent.erpStockQuantityGet(order);
                    if (!enough){
                        orderExamineVo.setExamineStatus(false);
                        orderExamineVo.setReason("商品吉客云库存不足");
                    }else {
                        //审核成功  调用erp系统创建订单 创建订单成功后修改订单状态为待发货
                        JackyunResponse jackyunResponse = jackClent.omsTradeOrderCreate(order);
                        if (!jackyunResponse.isSuccess()){
                            orderExamineVo.setExamineStatus(false);
                            orderExamineVo.setReason(jackyunResponse.getMsg());
                        }else {
                            com.alibaba.fastjson.JSONObject response = JsonUtils.deJson(jackyunResponse.toJson(), com.alibaba.fastjson.JSONObject.class);
                            OmsTradeOrderCreateResponseBizData responseBizData = response.getJSONObject("result").getJSONObject("data").toJavaObject(OmsTradeOrderCreateResponseBizData.class);
                            order.setErporderNo(responseBizData.getTradeOrder().getTradeNo());
                            order.setUpdateTime(new Date());
                            order.setOrderStatus(OrderStatus.APPROVED_PENDING_SHIPMENT.getCode());
                        }
                    }
                    tbOrderMapper.updateById(order);
                }
            } catch (Exception e) {
                log.error("订单审核异常", e);
                orderExamineVo.setExamineStatus(false);
                orderExamineVo.setReason("订单审核异常: " + e.getMessage());
            }
            list.add(orderExamineVo);
        }
        return R.ok(list);
    }

    private void doOrderCancel(TbOrder order) {
        if (order.getOrderType().equals(OrderType.POINTS_ONLY.getCode())){
            //1. 归还积分
            TbUser tbUser = tbUserMapper.selectById(order.getUserId());
            tbUser.setFreePoints(tbUser.getFreePoints() + order.getTotalPoints().intValue());
            tbUser.setTotalPoints(tbUser.getTotalPoints() + order.getTotalPoints().intValue());
            tbUserMapper.updateById(tbUser);
            //积分流水记录
            addPointsFlow(tbUser, 1, order.getOrderNo(), order.getTotalPoints(), "订单取消：" + order.getOrderNo());
        }
        //koc产品兑换
        if(order.getOrderType().equals(OrderType.KOC_EXCHANGE.getCode())){
            //归还koc产品兑换
//            TbUserKocProductLog tbUserKocProductLog = new TbUserKocProductLog();
//            tbUserKocProductLog.setStatus(0);
//            tbUserKocProductLogMapper.update(tbUserKocProductLog,new LambdaQueryWrapper<>(TbUserKocProductLog.class)
//                .eq(TbUserKocProductLog::getOrderId, order.getId()));
            TbProductExchangeCoupon tbProductExchangeCoupon = new TbProductExchangeCoupon();
            tbProductExchangeCoupon.setStatus(CouponStatusEnum.UNUSED.getCode());
            tbProductExchangeCoupon.setOrderId(null);
            tbProductExchangeCoupon.setUseTime(null);
            tbProductExchangeCouponMapper.update(tbProductExchangeCoupon,new LambdaQueryWrapper<>(TbProductExchangeCoupon.class)
                .in(TbProductExchangeCoupon::getOrderId,order.getId()));
        }
        //2. 恢复库存
        List<TbOrderItem> tbOrderItems = tbOrderItemMapper.selectList(new LambdaQueryWrapper<>(TbOrderItem.class).eq(TbOrderItem::getOrderId, order.getId()));
        for (TbOrderItem tbOrderItem:tbOrderItems) {
            TbProductSkus tbProductSkus = tbProductSkusMapper.selectById(tbOrderItem.getSkuId());
            tbProductSkus.setStock(tbProductSkus.getStock() + tbOrderItem.getQuantity());
            tbProductSkusMapper.updateById(tbProductSkus);
        }



    }

    @Override
    public R<Boolean> orderCancel(ExamineOrderDTO examineOrderDTO) {
        List<TbOrder> tbOrders = tbOrderMapper.selectList(new LambdaQueryWrapper<>(TbOrder.class).in(TbOrder::getId, examineOrderDTO.getIds()));
        for (TbOrder tbOrder:tbOrders){
            if (StringUtils.isBlank(tbOrder.getErporderNo())){
                return R.fail("存在未创建吉客云ERP订单的订单，无法取消");
            }
        }
        List<String> erpNos = tbOrders.stream().map(a -> a.getErporderNo()).collect(Collectors.toList());
        JackyunResponse jackyunResponse = jackClent.omsTradeOrderCancel(erpNos);
        if (jackyunResponse.isSuccess()){
            com.alibaba.fastjson.JSONObject response = JsonUtils.deJson(jackyunResponse.toJson(), com.alibaba.fastjson.JSONObject.class);
            OmsTradeOrderCancelResponseBizData responseBizData = response.getJSONObject("result").getJSONObject("data").toJavaObject(OmsTradeOrderCancelResponseBizData.class);
            if (responseBizData.getSuccess().equals( true)){
                TbOrder order=new TbOrder();
                order.setOrderStatus(OrderStatus.CANCELLED.getCode());
                order.setUpdateTime(new Date());
                order.setCancelTime(new Date());
                tbOrderMapper.update(order,new LambdaQueryWrapper<>(TbOrder.class).in(TbOrder::getId, examineOrderDTO.getIds()));
                //todo 通过mq异步退积分等
                for (TbOrder tbOrder:tbOrders) {
                    doOrderCancel(tbOrder);
                }
                return R.ok(true);
            }else {
                return R.fail(responseBizData.getFailedResults()[0].getMsg());
            }
        }else {
            return R.fail(jackyunResponse.getMsg());
        }
    }

    @Override
    public TableDataInfo<OrderVo> pointsMallOrder(OrderDTO dto) {
        LambdaQueryWrapper<TbOrder> eq=getQueryWrapper(dto);
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(dto.getPageNum());
        pageQuery.setPageSize(dto.getPageSize());
        Page<TbOrder> page = baseMapper.selectPage(pageQuery.build(), eq);
        List<OrderVo> orderVos = tbOrderToOrderVoList(page.getRecords());
        Page<OrderVo> tbOrderPage = new Page<>();
        tbOrderPage.setCurrent(page.getCurrent());
        tbOrderPage.setSize(page.getSize());
        tbOrderPage.setTotal(page.getTotal());
        tbOrderPage.setRecords(orderVos);
        return TableDataInfo.build(tbOrderPage);
    }
    private List<OrderVo> tbOrderToOrderVoList(List<TbOrder> records) {
        return records.stream().map(tbOrder -> {
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(tbOrder, orderVo);
            orderVo.setTbUser(tbUserMapper.selectById(tbOrder.getUserId()));
            orderVo.setTbUserAddress(tbUserAddressMapper.selectById(tbOrder.getAddressId()));
            List<TbOrderItem> tbOrderItems = tbOrderItemMapper.selectList(new LambdaQueryWrapper<>(TbOrderItem.class).eq(TbOrderItem::getOrderId, tbOrder.getId()));
            for (TbOrderItem tbOrderItem:tbOrderItems) {
                TbProductSkus tbProductSkus = tbProductSkusMapper.selectById(tbOrderItem.getSkuId());
                if (tbProductSkus!=null){
                    tbOrderItem.setTbProductSku(tbProductSkus);
                }
            }
            orderVo.setTbOrderItems(tbOrderItems);
            if (tbOrder.getOrderType()==3){
                orderVo.setTbProductExchangeCoupons(tbProductExchangeCouponMapper.selectList(new LambdaQueryWrapper<>(TbProductExchangeCoupon.class)
                    .eq(TbProductExchangeCoupon::getOrderId, tbOrder.getId()).eq(TbProductExchangeCoupon::getStatus, CouponStatusEnum.USED.getCode())));
            }
            return orderVo;
        }).collect(Collectors.toList());
    }

    @Override
    public OrderVo getDetilById(Long id) {
        TbOrder tbOrder = tbOrderMapper.selectById(id);
        OrderVo orderVo = tbOrderToOrderVo(tbOrder);
        return orderVo;
    }

    @Override
    public R<Boolean> pointsMallVer(Long userId, CreateOrderDTO dto) {
        TbProductSkus tbProductSkus = tbProductSkusMapper.selectById(dto.getSkuId());
        long totalPoints = tbProductSkus.getPointsNeeded() * dto.getQuantity();//校验积分是否充足
        Integer freePoints = tbUserMapper.selectById(userId).getFreePoints();
        Boolean isEnough =totalPoints>freePoints;
        Long aLong = tbProductExchangeCouponMapper.selectCount(new LambdaQueryWrapper<>(TbProductExchangeCoupon.class)
            .eq(TbProductExchangeCoupon::getUserId, userId).eq(TbProductExchangeCoupon::getStatus, CouponStatusEnum.UNUSED.getCode()));
        Boolean isEnoughCoupon = aLong<dto.getQuantity();
        if (isEnough&&isEnoughCoupon){
            return R.fail("用户积分和koc任务兑换卷不足");
        }
        return R.ok();
    }

    private OrderVo tbOrderToOrderVo(TbOrder tbOrder) {
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(tbOrder, orderVo);
            orderVo.setTbUser(tbUserMapper.selectById(tbOrder.getUserId()));
            orderVo.setTbUserAddress(tbUserAddressMapper.selectById(tbOrder.getAddressId()));
            List<TbOrderItem> tbOrderItems = tbOrderItemMapper.selectList(new LambdaQueryWrapper<>(TbOrderItem.class).eq(TbOrderItem::getOrderId, tbOrder.getId()));
            for (TbOrderItem tbOrderItem:tbOrderItems) {
                TbProductSkus tbProductSkus = tbProductSkusMapper.selectById(tbOrderItem.getSkuId());
                if (tbProductSkus!=null){
                    tbOrderItem.setTbProductSku(tbProductSkus);
                }
            }
            orderVo.setTbOrderItems(tbOrderItems);
            if (tbOrder.getOrderType()==3){
                orderVo.setTbProductExchangeCoupons(tbProductExchangeCouponMapper.selectList(new LambdaQueryWrapper<>(TbProductExchangeCoupon.class)
                    .eq(TbProductExchangeCoupon::getOrderId, tbOrder.getId()).eq(TbProductExchangeCoupon::getStatus, CouponStatusEnum.USED.getCode())));
            }
            return orderVo;
    }

    private LambdaQueryWrapper<TbOrder> getQueryWrapper(OrderDTO dto) {
        LambdaQueryWrapper<TbOrder> tbOrderLambdaQueryWrapper = new LambdaQueryWrapper<>(TbOrder.class)
            .ne(dto.getIsPointMall()!=null&&dto.getIsPointMall(),TbOrder::getOrderType, 0)
            .eq(dto.getIsPointMall()!=null&&!dto.getIsPointMall(),TbOrder::getOrderType, 0)
            .like(StringUtils.isNotBlank(dto.getOrderNo()),TbOrder::getOrderNo, dto.getOrderNo())
            .eq(dto.getOrderType() != null, TbOrder::getOrderType, dto.getOrderType())
            .eq(dto.getOrderStatus() != null, TbOrder::getOrderStatus, dto.getOrderStatus())
            .eq(dto.getOrderSource() != null, TbOrder::getOrderSource, dto.getOrderSource())
            .eq(dto.getUserId()!=null,TbOrder::getUserId, dto.getUserId())
            .eq(TbOrder::getIsDelete, 0)
            .like(StringUtils.isNotBlank(dto.getErporderNo()),TbOrder::getErporderNo, dto.getErporderNo())
            .between(StringUtils.isNotBlank(dto.getBeginTime()) && StringUtils.isNotBlank(dto.getEndTime()), TbOrder::getCreateTime, dto.getBeginTime(), dto.getEndTime())
            .orderByDesc(TbOrder::getCreateTime);
        if (StringUtils.isNotBlank(dto.getMobile())||StringUtils.isNotBlank(dto.getRealName())){
            LambdaQueryWrapper<TbUser> like = new LambdaQueryWrapper<>(TbUser.class).like(StringUtils.isNotBlank(dto.getMobile()), TbUser::getMobile, dto.getMobile())
                .like(StringUtils.isNotBlank(dto.getRealName()), TbUser::getRealName, dto.getRealName());
            List<TbUser> tbUsers = tbUserMapper.selectList(like);
            if (tbUsers.size()>0){
                tbOrderLambdaQueryWrapper.in(TbOrder::getUserId, tbUsers.stream().map(TbUser::getId).collect(Collectors.toList()));
            }else {
                tbOrderLambdaQueryWrapper.eq(TbOrder::getUserId, -1);
            }

        }
        return tbOrderLambdaQueryWrapper;
    }

    @Transactional(rollbackFor = Exception.class)
    public void addPointsFlow(TbUser user, Integer type, String orderNo, Long l, String s) {
        TbUserKocPointsLog tbUserKocPointsLog = new TbUserKocPointsLog();
        tbUserKocPointsLog.setUserId(user.getId());
        tbUserKocPointsLog.setType(type);
        tbUserKocPointsLog.setUserPhone(user.getMobile());
        tbUserKocPointsLog.setUserRealName(user.getRealName());
        tbUserKocPointsLog.setSourceType(3);
        tbUserKocPointsLog.setSourceId(orderNo);
        tbUserKocPointsLog.setRemarks(s);
        tbUserKocPointsLog.setKocPoint(l.intValue());
        tbUserKocPointsLog.setCreateTime(new Date());
        tbUserKocPointsLog.setUserRealName(user.getRealName());
        tbUserKocPointsLog.setUserKocLevelId(user.getKocLevelId());
        tbUserKocPointsLog.setUserPointOld(user.getTotalPoints()-l.intValue());
        tbUserKocPointsLogMapper.insert(tbUserKocPointsLog);
    }

    /**
     * 积分商城下单前置校验：仅校验积分兑换相关规则，纯金额入口不经过此逻辑
     *
     * @param quantity 购买数量
     */
    public R checkPointsExchangeEligibility(TbUser tbUser, TbProductSkus sku, Integer quantity,Boolean isUserKocProduct,List<Long> kocProductIds) {
        // 1. 查询SKU信息（重点获取积分兑换配置）
        if (sku == null) {
            return R.fail("商品不存在");
        }

        // 2. 校验该SKU是否支持积分兑换（仅exchange_type=1/2可走积分商城）
        if (sku.getExchangeType() == 0) {
            return R.fail("该商品仅支持纯金额购买，请前往普通商城下单");
        }

        // 3. 校验积分库存是否充足（仅积分兑换专用库存）
        if (sku.getStock() < quantity) {
            return R.fail("积分兑换库存不足，当前库存：" + sku.getStock());
        }

        // 4. 计算所需总积分，校验积分是否足够（无换算，固定需求）
        Long totalPointsNeeded = sku.getPointsNeeded() * quantity;
        if (!isUserKocProduct&&tbUser.getFreePoints() < totalPointsNeeded.intValue()) {
            return R.fail("积分不足，需" + totalPointsNeeded + "积分，当前仅" + tbUser.getFreePoints() + "积分，请前往普通商城纯金额购买");
        }
        if (isUserKocProduct){
            if (kocProductIds==null){
                return R.fail("koc兑换卷不能为空");
            }
            Long aLong = tbProductExchangeCouponMapper.selectCount(new LambdaQueryWrapper<>(TbProductExchangeCoupon.class)
                .eq(TbProductExchangeCoupon::getUserId, tbUser.getId())
                .eq(TbProductExchangeCoupon::getStatus, CouponStatusEnum.UNUSED.getCode())
                .in(TbProductExchangeCoupon::getId, kocProductIds));
            if (aLong<quantity){
                return R.fail("koc兑换卷数量不够");
            }
        }
        return R.ok();
    }
}
